package eu.codlab.androidemu.utilities;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Locale;

import eu.codlab.androidemu.gbcdroid.MainActivity;
import eu.codlab.src.game.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Environment;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;

public class MoveRomFileManager{
	private Activity _context;
	private ZipRead zipread = new ZipRead();

	public MoveRomFileManager(Activity context){
		_context = context;
	}
	NotificationManager mNotificationManager;

	private Notification getNotification(){
		// In this sample, we'll use the same text for the ticker and the expanded notification
		CharSequence text = _context.getText(R.string.app_label);

		// Set the icon, scrolling text and timestamp
		Notification notification = new Notification(R.drawable.notif_icon, text,
				System.currentTimeMillis());

		// The PendingIntent to launch our activity if the user selects this notification
		PendingIntent contentIntent = PendingIntent.getActivity(_context, 0,
				new Intent(_context, MainActivity.class), 0);

		// Set the info for the views that show in the notification panel.
		notification.setLatestEventInfo(_context, _context.getText(R.string.scanning_finish),
				text, contentIntent);
		return notification;
	}
	private Notification getNotification(String folder){
		// In this sample, we'll use the same text for the ticker and the expanded notification
		CharSequence text = _context.getText(R.string.app_label);

		// Set the icon, scrolling text and timestamp
		Notification notification = new Notification(R.drawable.notif_icon, text,
				System.currentTimeMillis());

		// The PendingIntent to launch our activity if the user selects this notification
		PendingIntent contentIntent = PendingIntent.getActivity(_context, 0,
				new Intent(_context, MainActivity.class), 0);

		// Set the info for the views that show in the notification panel.
		notification.setLatestEventInfo(_context, _context.getText(R.string.scanning_folder).toString().replace("%s", folder),
				text, contentIntent);
		return notification;
	}

	private static MoveRomFileManager _instance;

	public static MoveRomFileManager createInstance(Activity context, File path){
		if(_instance != null)
			return null;
		MoveRomFileManager instance = new MoveRomFileManager(context);
		instance._scan_files = new ArrayList<File>();
		instance._scan_files_zip = new ArrayList<File>();
		instance._scan_files.add(path);
		return instance;
	}
	public static MoveRomFileManager getInstance(){
		return _instance;
	}
	private ArrayList<File> _scan_files;
	private ArrayList<File> _scan_files_zip;

	public void startScan(){
		mNotificationManager =
				(NotificationManager) _context.getSystemService(Context.NOTIFICATION_SERVICE);

		Thread t = new Thread(){
			public void run(){
				while(_scan_files.size() > 0){
					// mId allows you to update the notification later on.
					mNotificationManager.notify(43, getNotification(_scan_files.get(0).getAbsolutePath()));
					addFromFolder(_scan_files.get(0).getAbsoluteFile());
				}

				_context.runOnUiThread(new Runnable(){
					public void run(){
						askFromZip(_scan_files_zip);
					}
				});
				_scan_files.clear();
				_scan_files = null;
				//_scan_files_zip.clear();
				//_scan_files_zip = null;
				_instance = null;
			}
		};
		t.start();
	}

	private final String [] filters = new String[]{"gba","gbc","gb","zip"};
	public boolean accept(File file) {
		String name = file.getName();

		// Do not show hidden files
		if (name.startsWith(".") || file.isDirectory())
			return false;

		if(name.endsWith(".zip")){
			return true;
		}
		name = name.toLowerCase(Locale.getDefault());
		for (String f : filters) {
			if(name.endsWith(f))
				return true;
		}
		return false;
	}
	public void addFromFolder(File folder){

		File[] files = folder.listFiles();
		if (files == null)
			files = new File[0];

		_scan_files.remove(0);

		for (File f : files) {
			if(".nomedia".equals(f.getName()))
				return;
		}
		for (File f : files) {
			if (f.isDirectory()){
				_scan_files.add(f);
			}else if(accept(f)){
				if(f.getName().endsWith(".zip")){
					Log.d("Found","zip "+f.getAbsolutePath());
					_scan_files_zip.add(f);
				}else if(f.getName().endsWith(".gba")){
					Log.d("Found","gba "+f.getAbsolutePath());
					addGBA(f);
				}else if(f.getName().endsWith(".gbc") || f.getName().endsWith(".gb")){
					Log.d("Found","gbc "+f.getAbsolutePath());
					addGBC(f);
				}
			}
		}
	}

	public void askFromZip(final ArrayList<File> zip){
		if(_context instanceof eu.codlab.androidemu.gbcdroid.MainActivity){
			((eu.codlab.androidemu.gbcdroid.MainActivity)_context).refresh();
		}else if(_context instanceof eu.codlab.androidemu.origbc.MainActivity){
			((eu.codlab.androidemu.origbc.MainActivity)_context).refresh();
		}
		Log.d("Obtaining gain"," info "+(zip==null ? true : false)+" "+(zip.size()==0 ? true: false));
		if(zip == null || zip.size() == 0){
			mNotificationManager.notify(43, getNotification());

			return;
		}

		final File zip1 = zip.get(0);
		zip.remove(0);
		Log.d("Scanning ", zip1.getAbsolutePath());
		zipread.compute(zip1);
		Log.d("Scanning finish", zip1.getAbsolutePath());

		if(zipread.isGBA() && false == zipread.isGBC()){
			addGBA(zip1);
			askFromZip(zip);
		}else if(false == zipread.isGBA() && zipread.isGBC()){
			addGBC(zip1);
			askFromZip(zip);
		}else if(zipread.isGBA() && zipread.isGBC()){
			AlertDialog.Builder alert = new AlertDialog.Builder(_context);
			alert.setTitle(R.string.move_zip_prompt_title);
			alert.setMessage(_context.getString(R.string.move_zip_prompt_message).replace("%s", zip1.getName()));
			alert.setPositiveButton(R.string.gba, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					addGBA(zip1);
					askFromZip(zip);
				}
			});
			alert.setNegativeButton(R.string.gbc, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					addGBC(zip1);
					dialog.dismiss();
					askFromZip(zip);
				}
			});
			alert.setNeutralButton(R.string.cancel, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					askFromZip(zip);
				}
			});

			alert.show();
		}else{
			//no gba or gbc/gbc game found
			askFromZip(zip);
		}
	}

	public void addGBA(File game){
		File gbc = new File(Environment.getExternalStorageDirectory(), "roms");
		gbc.mkdir();
		gbc = new File(gbc, "gba");
		gbc.mkdir();
		File nomedia = new File(gbc,".nomedia");
		if(!nomedia.exists())
			try {
				nomedia.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		int stripf = game.getAbsolutePath().lastIndexOf(".");
		if(stripf > 0){
			String name = game.getAbsolutePath().substring(0, stripf);
			File sav = new File(name+".sav");
			String new_name = game.getName().substring(0,game.getName().lastIndexOf("."));;
			move(sav, new File(gbc, new_name+".sav"));
			sav = new File(name+".png");
			move(sav, new File(gbc, new_name+".png"));
			for(int i=0;i<20;i++){
				sav = new File(name+".ss"+i);
				move(sav, new File(gbc, new_name+".ss"+i));
				sav = new File(name+".ss"+i+".png");
				move(sav, new File(gbc, new_name+".ss"+i+".png"));
			}
		}
		Log.d("moving from",game.getAbsolutePath());
		Log.d("moviiinngggg,",""+move(game.getAbsoluteFile(), new File(gbc,game.getName())));
		Log.d("moving from",new File(gbc,game.getName()).getAbsolutePath());
		
	}

	public boolean move(File from, File to){
		InputStream inStream = null;
		OutputStream outStream = null;

		try{

			inStream = new FileInputStream(from);
			outStream = new FileOutputStream(to);

			byte[] buffer = new byte[16*1024];

			int length;
			//copy the file content in bytes 
			while ((length = inStream.read(buffer)) > 0){
				outStream.write(buffer, 0, length);
			}

			inStream.close();
			outStream.close();

			//delete the original file
			from.delete();

			Log.d("move", "File is copied successful!");
			return true;
		}catch(IOException e){
			e.printStackTrace();
		}
		return false;
	}
	public void addGBC(File game){
		File gbc = new File(Environment.getExternalStorageDirectory(), "roms");
		gbc.mkdir();
		gbc = new File(gbc, "gbc");
		gbc.mkdir();
		File nomedia = new File(gbc,".nomedia");
		if(!nomedia.exists())
			try {
				nomedia.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}

		Log.d("moving from",game.getAbsolutePath());
		Log.d("moviiinngggg,",""+move(game.getAbsoluteFile(), new File(gbc,game.getName())));
		Log.d("moving from",new File(gbc,game.getName()).getAbsolutePath());
	}
	public static void promptUser(final Activity context){
		AlertDialog.Builder alert = new AlertDialog.Builder(context);

		alert.setTitle(R.string.move_prompt_title);
		alert.setMessage(R.string.move_prompt_message);

		// Set an EditText view to get user input 
		final EditText input = new EditText(context);
		alert.setView(input);

		alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				String value = input.getText().toString();
				if(getInstance() == null){
					File folder = new File(value);
					if(folder.exists() && folder.isDirectory()){
						MoveRomFileManager instance = createInstance(context, folder);
						instance.startScan();
					}else{
						Toast.makeText(context, "Incorrect folder /o/", Toast.LENGTH_LONG).show();
					}
				}
			}
		});

		alert.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
			}
		});

		alert.show();
	}
}
